<html>
<head>	
	<title>Extension Action</title> 
	<link type="text/css" href="css/custom-theme/jquery-ui-1.8.4.custom.css" rel="stylesheet" />
	<style type="text/css">
		body{ 
			font: 80% "Trebuchet MS", sans-serif; margin: 10px;
			background:#f5f5f5;
			width:350px;
			height: auto;
			overflow: auto;
			overflow-x: hidden;
			overflow-y: scroll;
			padding-top:0px;
			padding-bottom:5px;
			padding-right:15px;
			padding-left:5px;				
		}
		
		div.urlTitle{
			font-family: 'Arial', arial, serif;
			font-size:16px;
			font-style:italic;
			color:#000;
			text-align:center;
			padding:3px 0px 3px 0px;
			width:auto;
			height:auto;
			overflow: auto;
		}
		
		a.infoUrl{
			font-family: 'Arial', arial, serif;
			font-size:16px;
			font-style:italic;
			text-align:center;
			padding:0px 0px 0px 6px;
			width:auto;
			height:auto;
			overflow: auto;
		}		
		
		div.urlActionForm{
			text-align: center;

			font-family: 'Arial', arial, serif;
			font-size:14px;
			color:#000;
			text-decoration:none;
			
			width:340px;
			padding:0px 0px 0px 0px;
			margin:0px 0px 0px 0px;
			border:1px solid #DDD;
			
			white-space: wrap;
			overflow: auto;
			text-overflow: auto;
			
			display:none;
			-moz-border-radius:5px;
			-webkit-border-radius:5px;
			-o-border-radius:5px;
			border-radius:5px;

			background:#FFFFFF;
			background:-webkit-gradient(linear, 0% 0%, 0% 100%, from(#FFFFFF), to(#EEE));
			background:-moz-linear-gradient(0% 90% 90deg, #EEE, #FFF);			
		}
		
		div.urlActionForm:hover {
			color:#000;
			border-color:#3278BE;
		}		

		div.aRadioSetDiv {
			padding:0px 0px 5px 4px;
		}

		#bottomLinks {
			font-family: 'Arial', arial, serif;
			font-size:12px;
			color:#000;
			text-decoration:none;
			text-align:center;
			width:auto;
			margin:0px auto;
			padding:5px 5px 5px 5px;	
		}

		#divMultiSelect {
			text-align:center;
			width:auto;
			margin:0px 5px 0px 10px;
			display:none;
		}
		
		#cbMultiSelect {
			font-family: 'Arial', arial, serif;
			font-size:14px;
			color:#000;
		}
		
		#wrapperSpacerTop {
			width:auto;
			height:auto;
			margin:0px auto;
			padding:0px 5px 0px 5px;
			background: #f5f5f5;
			display:none;
			text-align: center;	
		}

		#wrapperSpacerBottom {
			width:auto;
			height:auto;
			margin:0px auto;
			padding:3px 5px 5px 5px;
			background: #f5f5f5;
			display:none;
			text-align: center;	
		}			

		button.actionButton {
			width:300px;
			height:auto;
			margin:5px auto;
			padding: 1px 2px 1px 2px;
			display:none;
			text-align: center;
			overflow: auto;
		}
		
		#dialog_link {padding: .4em 1em .4em 20px;text-decoration: none;position: relative;}
		#dialog_link span.ui-icon {margin: 0 5px 0 0;position: absolute;left: .2em;top: 50%;margin-top: -8px;}
		ul#icons {margin: 0; padding: 0;}
		ul#icons li {margin: 2px; position: relative; padding: 4px 0; cursor: pointer; float: left;  list-style: none;}
		ul#icons span.ui-icon {float: left; margin: 0 4px;}		
	</style>
		
	<script type="text/javascript" src="js/jquery-1.4.2.min.js"></script>
	<script type="text/javascript" src="js/jquery-ui-1.8.4.custom.min.js"></script>	
	
	<script src="CHANGE__PASSWORD__HERE.js"></script>
	<script src="common/common.js"></script>
	
</head>
<body onunload="doTasks();">

<button onclick="chrome.extension.getBackgroundPage().showOptionsPage(); window.close();" id="passwordBad" name="actionButton" class="actionButton">
	<span style="font-size:36px; color:red;">( ! )</span><br/><br/><span name="pwdProbDescrip">No password set for NotScripts.</span><br/>Will default deny scripts until changed.<br/><br/>Click for instructions.
</button> 
	
<button onclick="" id="fatalError" name="actionButton" class="actionButton">
		<span style="font-size:36px; color:red;">( ! )</span><br/><br/>NotScripts encountered invalid encryption for this site's settings / Exceeded storage quota on<br/><br/><span id="fatalErrorUrl" style="font-style:italic;"></span><br/>Click here to reset the<br/>HTML5 storage<br/>of the current web page.<br/><br/>Otherwise, please clear/enable the browser HTML5 storage.
</button>

<button onclick="chrome.extension.getBackgroundPage().clearSettings(); updateCurrentOnUnload=false; reloadCurrentAndClose();" id="extFatalError" name="actionButton" class="actionButton">
		<span style="font-size:36px; color:red;">( ! )</span><br/><br/>NotScripts encountered corrupted settings data in Google Chrome / Exceeded extension storage quota in Google Chrome.<br/><br/>Click here to clear<br/>the NotScripts settings lists<br/>to try to solve the problem.<br/><br/>Otherwise, please ensure Google Chrome has javascript and HTML5 storage enabled.<br/><br/>Contact the author of NotScripts if you repeatedly get this message.
</button>
 
<button id="revokeAllTemp" name="actionButton" class="actionButton">Revoke All Temporary</button>	 
<div id="divMultiSelect">
	<input type="checkbox" id="cbMultiSelect" name="cbMultiSelect" onclick="bgPage.config.set('multiSelect', this.checked)"; />
	<label for="cbMultiSelect">Multi-Select Sites</label>
</div>

<div id="wrapperSpacerTop" class="wrapperSpacer"><hr/></div> 	
<div id="wrapperSpacerBottom" class="wrapperSpacer"><hr/></div>

<button id="tempAllowAllShown" name="actionButton" class="actionButton" onclick="tempAllowShownBlocked();">Temporarily Allow Shown Blocked</button>	
<button id="allowAllShown" name="actionButton" class="actionButton" onclick="allowAllShown();">Allow All Shown</button>
<button id="blockAllShown" name="actionButton" class="actionButton" onclick="blockAllShown();">Block All Shown</button>				 	
<button id="globalAllowTemp" name="actionButton" class="actionButton">Globally Allow All Temporarily</button>			

<div id="bottomLinks">
	<a href="#" onclick="chrome.extension.getBackgroundPage().showOptionsPage(); window.close();">Options</a>
	<a href="#" onclick="chrome.tabs.create({'url': 'http://www.optimalcycling.com'}); window.close();" style="padding-left:3px">Home</a>
</div>

<div id="spaceFiller" style="display:none; height:150px"></div> 

<script type = "text/javascript">

var currTabId = null;
var currTabIndex = null;
var currTabUrl = null;

var numActionShown = 0;
const MAX_NUM_ACTION = 150;

var fatalErrorButton = document.getElementById("fatalError");
var extFatalErrorButton = document.getElementById("extFatalError");
var passwordBadButton = document.getElementById("passwordBad");
var spacerTopDiv = document.getElementById("wrapperSpacerTop");
var spacerBottomDiv = document.getElementById("wrapperSpacerBottom");

var multiSelectCB = document.getElementById("cbMultiSelect");
var multiSelectDiv = document.getElementById("divMultiSelect");

var allowAllShownButton = document.getElementById("allowAllShown");
var blockAllShownButton = document.getElementById("blockAllShown");
var tempAllowShownBlockedButton = document.getElementById("tempAllowAllShown");
var globalAllowTempButton = document.getElementById("globalAllowTemp");
var revokeAllTempButton = document.getElementById("revokeAllTemp");

$("button[name=actionButton]").button();

var encounteredError = false;
const bgPage = chrome.extension.getBackgroundPage();

var passwordStatus = isPasswordGood();
if (passwordStatus !== PASSWORD_STATUS.okay)
{
	switch (passwordStatus)
	{
		case PASSWORD_STATUS.tooShort:	
			$("span[name=pwdProbDescrip]").text("Problem: Password is too short, must be at least " + MIN_PASSWORD_LENGTH + " characters.");
			break;
		case PASSWORD_STATUS.tooLong:
			$("span[name=pwdProbDescrip]").text("Problem: Password is too long, must be no greater than " + MAX_PASSWORD_LENGTH + " characters.");
			break;
		case PASSWORD_STATUS.empty:
			$("span[name=pwdProbDescrip]").text("Problem: Password is empty.");
			break;
		case PASSWORD_STATUS.invalidChars:
			$("span[name=pwdProbDescrip]").text("Problem: Password contains invalid characters.");
			break;
		case PASSWORD_STATUS.okay:
			break;
		case PASSWORD_STATUS.undefined:
			$("span[name=pwdProbDescrip]").text("Problem: Your password file is missing/invalid characters are present/the syntax is incorrect.");
			break;			
		default:	
			$("span[name=pwdProbDescrip]").text("Problem: Unknown problem with password/file.");
			break;			
	}
	passwordBadButton.style.display = "block";
}
else if (bgPage.extFatalError)
{
	chrome.tabs.getSelected(null, 
		function(tab)
		{	
			currTabId = tab.id;
			currTabIndex = tab.index;
			currTabUrl = tab.url;			
		}
	);
	extFatalErrorButton.style.display = "block";
	spacerTopDiv.style.display = "block";
}
else
{
	chrome.extension.onRequest.addListener(function(msg, src, send) {
		if (msg.type === "get sources response")
		{	
			//chrome.extension.getBackgroundPage().console.log("sources from iframe");
			showLastBlocked(msg);
			send({});
		}
		else
		{
			send({});
		}
	});

	chrome.tabs.getSelected(null, 
		function(tab)
		{	
			currTabId = tab.id;
			currTabIndex = tab.index;
			currTabUrl = tab.url;
			chrome.tabs.sendRequest(tab.id, {type: "get sources"}, showLastBlocked);
				
		}
	);
}



function chunkUrlForDisplay(currBlockedURL)
{
	const maxLines = 5;
	var urlChunks = currBlockedURL.chunk(30);
	var theMessage = "";
	
	if (urlChunks)
	{
		for (var j = 0; j < maxLines && j < urlChunks.length; j++)
		{
			theMessage += (urlChunks[j] + "\n");
		}
		
		if (urlChunks.length > maxLines)
		{
			var lastChunk = urlChunks[maxLines].chunk(15);
			theMessage += (lastChunk[0] + "......\n");
		}
	}
	
	return theMessage;
}

const URL_LIST_TYPE = {
	"allowed": 0,
	"tempAllowed": 1,
	"blocked": 2,
	"untrusted": 3
}

function limitUrlLength(currBlockedURL)
{
	return (currBlockedURL.length >= 300 ? currBlockedURL.substring(0, 299) + "......<<CUT OFF, TOO LONG>>" : currBlockedURL);
}

/*
In case we have duplicates from iframes or unknown TLD's. Uses linear search to go through the already shown elements.
Probably best to not try a binary-like search on the shown elements because of the small numbers (~less than 10).
*/
function fixAlreadyShown(currBlockedURL)
{
	var isAlreadyShown = false;
	var docEls = document.getElementsByName("urlActionForm");
	for (var i = 0; i < docEls.length; i++)
	{
		var currDataUrl = docEls[i].childNodes[1].childNodes[0].getAttribute("data-url");
		//console.log("outside  " + currBlockedURL + "    " + currDataUrl);
		if (patternMatches(currBlockedURL, currDataUrl))
		{
			//console.log("matches    " + currBlockedURL  + "    " + currDataUrl);
			if (currBlockedURL.length < currDataUrl.length)
			{
				var currUrlTitleEl = docEls[i].childNodes[0];	//.childNodes[0];
				var currRBs = docEls[i].childNodes[1].childNodes;	// Goes in multiples of 2
				
				currUrlTitleEl.innerText = limitUrlLength(currBlockedURL);
				var infoUrl = document.createElement("a");
				infoUrl.className = "infoUrl";
				infoUrl.href = "#";
				infoUrl.innerText = "(?)";
				infoUrl.setAttribute("data-url", currBlockedURL);
				infoUrl.onclick = openInfoUrl;				
				currUrlTitleEl.appendChild(infoUrl);				
				
				currRBs[0].setAttribute("data-url", currBlockedURL);	// Allow						
				currRBs[2].setAttribute("data-url", currBlockedURL);	// Block This Site
				currRBs[4].setAttribute("data-url", currBlockedURL);	// Temp
				
				if (currRBs[6])
					currRBs[6].setAttribute("data-url", currBlockedURL);	// In case we have an extra button
			}

			isAlreadyShown = true;								
		}		
	}
	return isAlreadyShown;	
}

function addButtonsFromUrlList(urlList, urlListType, topDomain, topDomainIsWhitelisted)
{
	if (urlList)
	{
		for (var i = 0; i < urlList.length; i++)
		{
			// Note: It is expected and important that the urlList is already encoded with encodeURI,
			// which it should be if urlList was filled using only returned values from getPrimaryDomain(...)
			// Otherwise, we will have unexpected formatting when rendering the text if there are malformed strings.
			var currBlockedURL = urlList[i];
			
			if (currBlockedURL)
			{					
				if (fixAlreadyShown(currBlockedURL))
					continue;				
				
				if (numActionShown > MAX_NUM_ACTION)
				{
					var overFlowMsg = document.createElement("div");
					overFlowMsg.className = "urlActionForm";
					overFlowMsg.setAttribute("name", "urlActionForm");
					overFlowMsg.style.padding = "5px 0px 5px 0px";
					overFlowMsg.innerText = "Overflow.....too many scripts. At least " + (urlList.length - i) + " more.\nMalicious site?";
					spacerBottomDiv.parentNode.insertBefore(overFlowMsg,spacerBottomDiv);
					overFlowMsg.style.display = "block";					
					break;
				}
				
				numActionShown++;
				
				var aForm = document.createElement("div");
				aForm.className = "urlActionForm";
				aForm.setAttribute("name", "urlActionForm");
				var aRadioSetDiv = document.createElement("div");
				aRadioSetDiv.className = "aRadioSetDiv";				
		
		
				var divUrl = document.createElement("div");
				divUrl.className = "urlTitle";
				divUrl.innerText = limitUrlLength(currBlockedURL);
				
				var infoUrl = document.createElement("a");
				infoUrl.className = "infoUrl";
				infoUrl.href = "#";
				infoUrl.innerText = "(?)";
				infoUrl.setAttribute("data-url", currBlockedURL);
				infoUrl.onclick = openInfoUrl;				
				divUrl.appendChild(infoUrl);				

				aForm.appendChild(divUrl);
				
				
				var rbGroupName = randomID();
				
				var rbAlwaysAllow = document.createElement("input");
				rbAlwaysAllow.type = "radio";
				rbAlwaysAllow.id = randomID();
				rbAlwaysAllow.name = rbGroupName;
				rbAlwaysAllow.setAttribute("data-url", currBlockedURL);
				rbAlwaysAllow.onclick = addSite;
				if (urlListType === URL_LIST_TYPE.allowed) rbAlwaysAllow.checked = true;				
				aRadioSetDiv.appendChild(rbAlwaysAllow);
				var labelAlwaysAllow = document.createElement("label");
				labelAlwaysAllow.setAttribute("for", rbAlwaysAllow.id);
				labelAlwaysAllow.innerText = "Allow";
				aRadioSetDiv.appendChild(labelAlwaysAllow);
				
				var rbBlock = document.createElement("input");
				rbBlock.type = "radio";
				rbBlock.id = randomID();
				rbBlock.name = rbGroupName;
				rbBlock.setAttribute("data-url", currBlockedURL);
				rbBlock.onclick = removeSite;
				if ((urlListType === URL_LIST_TYPE.blocked && blocking_mode !== BMODE_TYPES.WHITELIST_ALLOW_TOP_LEVEL)
					|| (urlListType === URL_LIST_TYPE.untrusted && blocking_mode === BMODE_TYPES.WHITELIST_ALLOW_TOP_LEVEL)) 
					rbBlock.checked = true;				
				aRadioSetDiv.appendChild(rbBlock);
				var labelBlock = document.createElement("label");
				labelBlock.setAttribute("for", rbBlock.id);
				labelBlock.innerText = blocking_mode === BMODE_TYPES.WHITELIST_ALLOW_TOP_LEVEL ? "Block Site" : "Block From Site";
				aRadioSetDiv.appendChild(labelBlock);	
				
				if (blocking_mode === BMODE_TYPES.WHITELIST_ALLOW_TOP_LEVEL)
				{
					var rbSameSite = document.createElement("input");
					rbSameSite.type = "radio";
					rbSameSite.id = randomID();
					rbSameSite.name = rbGroupName;
					rbSameSite.setAttribute("data-url", currBlockedURL);
					rbSameSite.onclick = sameSite;
					if (urlListType === URL_LIST_TYPE.blocked 
						|| (urlListType === URL_LIST_TYPE.allowed && topDomain === currBlockedURL && !topDomainIsWhitelisted)) 
						rbSameSite.checked = true;				
					aRadioSetDiv.appendChild(rbSameSite);
					var labelSameSite = document.createElement("label");
					labelSameSite.setAttribute("for", rbSameSite.id);
					labelSameSite.innerText = "Same";
					aRadioSetDiv.appendChild(labelSameSite);				
				}				
				
				var rbTempAllow = document.createElement("input");
				rbTempAllow.type = "radio";
				rbTempAllow.id = randomID();
				rbTempAllow.name = rbGroupName;
				rbTempAllow.setAttribute("data-url", currBlockedURL);
				rbTempAllow.onclick = tempAllowSite;
				if (urlListType === URL_LIST_TYPE.tempAllowed) rbTempAllow.checked = true;
				aRadioSetDiv.appendChild(rbTempAllow);
				var labelTempAllow = document.createElement("label");
				labelTempAllow.setAttribute("for", rbTempAllow.id);
				labelTempAllow.innerText = "Temp";
				aRadioSetDiv.appendChild(labelTempAllow);
				
				$(aRadioSetDiv).buttonset();
				
				aForm.appendChild(aRadioSetDiv);
				spacerBottomDiv.parentNode.insertBefore(aForm,spacerBottomDiv);
				aForm.style.display = "block";		
			}
		}
	}
}

function showLastBlocked(response)
{		
	if (response.fatalError)
	{
		encounteredError = true;
		
		var currBlockedURL = encodeURI(response.url ? response.url : "");
		document.getElementById("fatalErrorUrl").innerText = chunkUrlForDisplay(currBlockedURL);	
		fatalErrorButton.onclick = clearSiteStorageAndClose;
		fatalErrorButton.style.display = "block";
		spacerTopDiv.style.display = "block";
	}
	
	// Toggling on/off
	if (response.globalAllowAll)
	{
		revokeAllTempButton.style.margin = "30px auto 10px auto";
		revokeAllTempButton.setAttribute("data-newState", "false");
		revokeAllTempButton.style.display = "block";		
		revokeAllTempButton.onclick = toggleOnOff;
	}
	else
	{
		multiSelectDiv.style.display = "block";
		multiSelectCB.checked = bgPage.config.get('multiSelect');
		spacerTopDiv.style.display = "block";
		
		if (bgPage.tempAllowList.length > 0)
		{
			revokeAllTempButton.innerText = "Revoke Temporary From\n" + bgPage.tempAllowList.length + " Site(s)\nin All Pages";
			revokeAllTempButton.style.padding = "7px 2px 7px 2px";
			revokeAllTempButton.setAttribute("data-newState", "false");
			revokeAllTempButton.style.display = "block";
			revokeAllTempButton.onclick = toggleOnOff;
		}
		
		spacerBottomDiv.style.display = "block";
		if (response.pageSourcesForbidden && response.pageSourcesForbidden.length > 0)
		{
			allowAllShownButton.style.display = "block";			
			tempAllowShownBlockedButton.style.display = "block";
		}
		
		if (response.pageSourcesAllowed && response.pageSourcesAllowed.length > 0)
		{
			blockAllShownButton.style.display = "block";	
		}
	
		globalAllowTempButton.setAttribute("data-newState", "true");
		globalAllowTempButton.style.display = "block";
		globalAllowTempButton.onclick = toggleOnOff;

		addButtonsFromUrlList(response.pageSourcesTempAllowed, URL_LIST_TYPE.tempAllowed, response.topDomain, response.topDomainIsWhitelisted);
		addButtonsFromUrlList(response.pageSourcesAllowed, URL_LIST_TYPE.allowed, response.topDomain, response.topDomainIsWhitelisted);
		
		// Untrust needs to be before blocked in case of iframes
		addButtonsFromUrlList(response.pageSourcesUntrusted, URL_LIST_TYPE.untrusted, response.topDomain, response.topDomainIsWhitelisted);	
		addButtonsFromUrlList(response.pageSourcesForbidden, URL_LIST_TYPE.blocked, response.topDomain, response.topDomainIsWhitelisted);
		
	}

	// Workaround for Google Chrome on netbooks with screen heights of less than 700px where the 
	// drop down menu is cut off by the screen. 
	if (screen.height < 700 && document.documentElement.clientHeight > 500)
	{
		document.getElementById("spaceFiller").style.display = "block";
	}	
}

var updateCurrentOnUnload = false;

function doTasks()
{
	if (updateCurrentOnUnload)
		bgPage.updateAllTabs(false);
}

function openInfoUrl()
{
	var url = this.getAttribute("data-url");
	chrome.tabs.create({"url": "http://www.google.com/safebrowsing/diagnostic?site=" + encodeURIComponent(url), "index": currTabIndex});
	window.close();
}

function tempAllowSite()
{
	var urls = new Array();
	urls.push(this.getAttribute("data-url"));
	bgPage.tempPermitUrl(urls);
	
	if (multiSelectCB.checked)
		updateCurrentOnUnload = true;
	else
	{
		bgPage.updateAllTabs(false);
		window.close();
	}
}

function removeSite() {
	var urls = new Array();
	urls.push(this.getAttribute("data-url"));
	bgPage.revokeUrl(urls);
	
	if (multiSelectCB.checked)
		updateCurrentOnUnload = true;
	else
	{
		bgPage.updateAllTabs(false);
		window.close();
	}
}

function addSite() {	
	var urls = new Array();
	urls.push(this.getAttribute("data-url"));
	bgPage.permitUrl(urls);		

	if (multiSelectCB.checked)
		updateCurrentOnUnload = true;
	else
	{
		bgPage.updateAllTabs(false);
		window.close();
	}
}

function sameSite() {
	var urls = new Array();
	urls.push(this.getAttribute("data-url"));
	bgPage.sameSiteUrl(urls);
	
	if (multiSelectCB.checked)
		updateCurrentOnUnload = true;
	else
	{
		bgPage.updateAllTabs(false);
		window.close();
	}
}

function blockAllShown()
{
	var urls = new Array();
	var docEls = document.getElementsByName("urlActionForm");
	for (var i = 0; i < docEls.length; i++)
	{
		urls.push(docEls[i].childNodes[1].childNodes[0].getAttribute("data-url"));
	}
	bgPage.revokeUrl(urls);

	updateCurrentOnUnload = false;
	bgPage.updateAllTabs(false);
	window.close();
}

function allowAllShown()
{
	var urls = new Array();
	var docEls = document.getElementsByName("urlActionForm");
	for (var i = 0; i < docEls.length; i++)
	{
		urls.push(docEls[i].childNodes[1].childNodes[0].getAttribute("data-url"));
	}
	bgPage.permitUrl(urls);

	updateCurrentOnUnload = false;
	bgPage.updateAllTabs(false);
	window.close();
}

function tempAllowShownBlocked()
{
	var urls = new Array();
	var docEls = document.getElementsByName("urlActionForm");
	for (var i = 0; i < docEls.length; i++)
	{
		// The second childNodes goes in multiples of 2 because jQuery renders an element over the radio boxes
		if (!docEls[i].childNodes[1].childNodes[0].checked)		// Looks at the "Allow" button
			urls.push(docEls[i].childNodes[1].childNodes[0].getAttribute("data-url"));
	}
	bgPage.tempPermitUrl(urls);
	
	updateCurrentOnUnload = false;
	bgPage.updateAllTabs(false);
	window.close();
}


function toggleOnOff() {	
	var newState = this.getAttribute("data-newState") === "true" ? true : false;
	bgPage.toggleOnOff(newState);	
	bgPage.updateAllTabs(false);
	window.close();
}

function clearSiteStorageAndClose()
{
	bgPage.resetSiteStorage(currTabId);
	window.close();
}

function reloadCurrentAndClose()
{
	chrome.tabs.update(currTabId, {"url": currTabUrl});
	window.close();
}
</script>

</body>
</head>
</html>